﻿#include "SequenceLinke.h"
#include "SinglyLink.h"
#include "DoubleLinke.h"
// C/C++ 学习网站：https://legacy.cplusplus.com 注意旧版本（搜索）和新版本

int	main()
{
	// 测试顺序表
	{
		print_start_line("顺序表测试");
		// 定义顺序表
		sqli sqe1;
		seq_list_init(&sqe1, 5); // 初始化顺序表

		// 顺序表尾部添加元素
		add_elem_end(&sqe1, 15);
		add_elem_end(&sqe1, 7);
		add_elem_end(&sqe1, 3);
		add_elem_end(&sqe1, 2);
		add_elem_end(&sqe1, 14);
		add_elem_end(&sqe1, 6);
		add_elem_end(&sqe1, 8);
		add_elem_end(&sqe1, 5);
		add_elem_end(&sqe1, 9);
		add_elem_end(&sqe1, 10);
		add_elem_end(&sqe1, 1);
		add_elem_end(&sqe1, 16);
		add_elem_end(&sqe1, 12);

		// 显示顺序表
		show_all_elem(&sqe1);
		show_index_elem(&sqe1, 2);

		// 查找元素
		search_elem(&sqe1, 3);

		// 顺序表尾部删除元素
		del_elem_end(&sqe1);
		show_all_elem(&sqe1);

		// 顺序表头部添加元素
		add_elem_head(&sqe1, 4);
		show_all_elem(&sqe1);

		// 顺序表头部删除元素
		del_elem_head(&sqe1);
		show_all_elem(&sqe1);

		// 顺序表中间添加元素
		insert_index_elem(&sqe1, 2, 100);
		show_all_elem(&sqe1);

		// 顺序表删除元素
		del_elem(&sqe1, 2);
		del_elem(&sqe1, 99);
		show_all_elem(&sqe1);

		// 顺序表删除指定位置元素
		del_index_elem(&sqe1, 3);
		show_all_elem(&sqe1);

		// 顺序表修改元素
		modify_index_elem(&sqe1, 2, 13);
		show_all_elem(&sqe1);

		// 顺序表合并（两个顺序表合并）
		merge_seq_list(&sqe1, &sqe1);
		show_all_elem(&sqe1);

		// 顺序表逆序
		reverse_seq_list(&sqe1);
		show_all_elem(&sqe1);

		// 顺序表排序
		sort_seq_list(&sqe1);
		show_all_elem(&sqe1);

		// 查看顺序表长度
		printf("顺序表长度：%zd\n", get_seq_list_len(&sqe1));

		// 释放顺序表
		seq_list_destroy(&sqe1);

		print_end_line("顺序表测试");
	}

	// 测试栈和队列待补充

	// 测试单链表
	{
		print_start_line("单链表测试");
		// 定义单链表头节点指针
		single_node* single_head = create_single_node(1); // 定义单链表节点

		// 单链表头部添加元素
		add_head_single_node(&single_head, 2);
		printf_single_list(single_head);

		// 单链表头部删除元素
		del_head_single_node(&single_head);
		printf_single_list(single_head);

		// 单链表尾部添加元素
		add_end_single_node(&single_head, 3);
		printf_single_list(single_head);
		printf("单链表长度：%zd\n", get_single_list_len(single_head)); // 输出单链表长度

		// 单链表尾部删除元素
		del_end_single_node(&single_head);
		printf_single_list(single_head);

		// 单链表中间添加元素
		insert_single_node(&single_head, 0, 4);
		insert_single_node(&single_head, 1, 9);
		insert_single_node(&single_head, 3, 5);
		insert_single_node(&single_head, 2, 7);
		insert_single_node(&single_head, 4, 11);
		insert_single_node(&single_head, 2, 8);
		printf_single_list(single_head);

		// 单链表删除中间指定位置元素
		del_single_node(&single_head, 3);
		printf_single_list(single_head);

		// 单链表删除指定元素
		del_num_single_list(&single_head, 7);
		printf_single_list(single_head);

		// 单链表翻转
		reverse_single_list1(&single_head);
		printf_single_list(single_head);
		single_head = reverse_single_list2(single_head);
		// 另一种翻转方法，返回翻转后的头节点指针，使用该方法原链表指针依然指向原链表的头节点
		// 需要手动调整原链表指针，重新指向翻转后的头节点指针
		printf_single_list(single_head);

		// 单链表查找元素
		search_num_single_list(single_head, 9);
		search_num_single_list(single_head, 20);

		// 单链表合并
		single_node* single_head2 = create_single_node(12);
		add_end_single_node(&single_head2, 17);
		add_end_single_node(&single_head2, 4);
		add_end_single_node(&single_head2, 6);
		add_head_single_node(&single_head2, 19);
		add_end_single_node(&single_head2, 3);
		add_end_single_node(&single_head2, 15);
		li1_add_li2(single_head, single_head2);
		printf_single_list(single_head);

		// 单链表排序
		bubble_sort_singly_linke(single_head); // 起名长了，懒得读，换中文好识别（只供学习）
		printf_single_list(single_head);

		// 单链表销毁
		destroy_single_list(single_head);
		single_head = NULL; // 手动置空原链表指针，防止堆区内存的访问
		//destroy_single_list(single_head2); // 销毁另一个单链表，这里已经被销毁，不用再销毁
		single_head2 = NULL; // 手动置空另一个链表指针，防止堆区内存的访问
		print_end_line("单链表测试");
	}

	// 测试双链表
	{
		print_start_line("双链表测试");
		// 定义双链表头节点指针
		double_node* double_head = create_double_node(1); // 定义双链表节点

		// 双链表头部添加元素
		printf("双链表增加与删除元素测试：\n");
		add_head_double_node(&double_head, 2);
		printf_double_list(double_head);

		// 双链表头部删除元素
		del_head_double_node(&double_head);
		printf_double_list(double_head);

		// 双链表尾部添加元素
		add_end_double_node(&double_head, 21);
		add_end_double_node(&double_head, 12);
		add_end_double_node(&double_head, 8);
		add_end_double_node(&double_head, 4);
		printf_double_list(double_head);

		// 双链表尾部删除元素
		del_end_double_node(&double_head);
		printf_double_list(double_head);

		// 双向链表的长度
		printf("双链表长度：%zd\n", get_double_list_len(double_head)); // 输出双链表长度

		// 双链表中间添加元素
		insert_double_node(&double_head, 0, 3);
		insert_double_node(&double_head, 1, 7);
		insert_double_node(&double_head, 3, 5);
		insert_double_node(&double_head, 2, 11);
		insert_double_node(&double_head, 4, 13);
		insert_double_node(&double_head, 2, 9);
		printf_double_list(double_head);

		// 双链表删除中间指定位置元素
		del_double_node(&double_head, 3);
		printf_double_list(double_head);

		// 双链表删除指定元素
		printf("双链表删除指定元素测试：\n");
		del_num_double_list(&double_head, 8);
		del_num_double_list(&double_head, 66);
		printf_double_list(double_head);

		// 双链表翻转
		printf("双链表翻转测试：\n");
		reverse_double_list1(&double_head);
		printf_double_list(double_head);
		double_head = reverse_double_list2(double_head);
		// 递归翻转方法，返回翻转后的头节点指针，使用该方法原链表指针依然指向原链表的头节点
		// 需要手动调整原链表指针，重新指向翻转后的头节点指针
		printf_double_list(double_head);

		// 双链表查找元素
		search_num_double_list(double_head, 11);
		search_num_double_list(double_head, 300);

		// 双链表合并
		printf("双链表合并测试：\n");
		double_node* double_head2 = create_double_node(12);
		add_end_double_node(&double_head2, 17);
		add_end_double_node(&double_head2, 4);
		add_end_double_node(&double_head2, 6);
		add_head_double_node(&double_head2, 19);
		add_end_double_node(&double_head2, 3);
		add_end_double_node(&double_head2, 15);
		dli1_add_dli2(double_head, double_head2);
		printf_double_list(double_head);

		// 双链表的前后节点打印
		/*printf("打印前后节点数据：\n");
		打印前后节点数据(double_head);*/

		// 双链表排序
		//insertion_sort_doubly_linke(double_head);
		quick_sort_doubly_linked(double_head);
		printf_double_list(double_head);
		print_front_and_end(double_head);

		// 双链表的销毁
		destroy_double_list(double_head);
		double_head = NULL; // 手动置空原链表指针，防止堆区内存的访问
		print_end_line("双链表测试");
	}

	// 测试哈希表待补充

	// 测试树待补充

	system("pause"); // 等待用户输入
	return 0;
}
